package com.yikes.srb.web.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *  返回页面-下拉选项对象
 * </p>
 *
 * @Author: guanrong.yin
 * @Date: 2024/12/1 22:27
 */
@Data
@ToString
@AllArgsConstructor
public class OptionNodeVO<T> {

    /**
     * 下拉框数据
     */
    private Collection<Node<T>> data;

    /**
     * 默认值
     */
    private T defaultValue;


    /**
     * @param list list集合
     * @param id   下拉框 value
     * @param name 下拉框显示值
     * @param <T>  泛型
     * @param <V>  泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(Collection<V> list, Function<V, T> id, Function<V, String> name) {
        List<Node<T>> collect = list.stream().map(m -> new Node<T>(id.apply(m), name.apply(m))).collect(Collectors.toList());
        return new OptionNodeVO<>(collect, null);
    }

    /**
     * @param list list集合
     * @param id   下拉框 value
     * @param name 下拉框显示值
     * @param <T>  泛型
     * @param <V>  泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(Collection<V> list, Function<V, T> id, Function<V, String> name, Function<V, ?> value1) {
        List<Node<T>> collect = list.stream().map(m -> new Node<T>(id.apply(m), name.apply(m), value1.apply(m))).collect(Collectors.toList());
        return new OptionNodeVO<>(collect, null);
    }

    /**
     * @param list list集合
     * @param id   下拉框 value
     * @param name 下拉框显示值
     * @param <T>  泛型
     * @param <V>  泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(Collection<V> list, Function<V, T> id,
                                                Function<V, String> name,
                                                Function<V, ?> value1,
                                                Function<V, ?> value2) {
        List<Node<T>> collect = list.stream()
                .map(m -> new Node<T>(id.apply(m), name.apply(m), value1.apply(m), value2.apply(m)))
                .collect(Collectors.toList());
        return new OptionNodeVO<>(collect, null);
    }

    /**
     * @param list list集合
     * @param id   下拉框 value
     * @param name 下拉框显示值
     * @param <T>  泛型
     * @param <V>  泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(Collection<V> list, Function<V, T> id,
                                                Function<V, String> name,
                                                Function<V, ?> value1,
                                                Function<V, ?> value2,
                                                Function<V, ?> value3) {
        List<Node<T>> collect = list.stream()
                .map(m -> new Node<T>(id.apply(m), name.apply(m), value1.apply(m), value2.apply(m), value3.apply(m)))
                .collect(Collectors.toList());
        return new OptionNodeVO<>(collect, null);
    }

    public static <T, V> OptionNodeVO<T> covert(Collection<V> list, Function<V, T> id,
                                                Function<V, String> name,
                                                Function<V, ?> value1,
                                                Function<V, ?> value2,
                                                Function<V, ?> value3,
                                                Function<V, ?> value4) {
        List<Node<T>> collect = list.stream()
                .map(m -> new Node<T>(id.apply(m), name.apply(m), value1.apply(m), value2.apply(m), value3.apply(m), value4.apply(m)))
                .collect(Collectors.toList());
        return new OptionNodeVO<>(collect, null);
    }


    /**
     * @param list         list集合
     * @param id           下拉框 value
     * @param name         下拉框显示值
     * @param defaultValue 默认值
     * @param <T>          泛型
     * @param <V>          泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(T defaultValue, Collection<V> list, Function<V, T> id, Function<V, String> name) {
        List<Node<T>> collect = list.stream().map(m -> new Node<T>(id.apply(m), name.apply(m))).collect(Collectors.toList());
        return new OptionNodeVO<>(collect, defaultValue);
    }

    /**
     * @param list         list集合
     * @param id           下拉框 value
     * @param name         下拉框显示值
     * @param defaultValue 默认值
     * @param <T>          泛型
     * @param <V>          泛型
     * @return OptionNodeVO
     */
    public static <T, V> OptionNodeVO<T> covert(T defaultValue, Collection<V> list, Function<V, T> id, Function<V, String> name, Function<V, ?> param2) {
        List<Node<T>> collect = list.stream().map(m -> new Node<T>(id.apply(m), name.apply(m), param2.apply(m))).collect(Collectors.toList());
        return new OptionNodeVO<>(collect, defaultValue);
    }

    /**
     * @param map
     * @param <V> 泛型
     * @return OptionNodeVO
     */
    public static <V> OptionNodeVO<V> covert(Map<V, String> map) {
        return covert(map, null);
    }

    /**
     * @param map          map对象
     * @param defaultValue 默认值
     * @param <V>          泛型
     * @return OptionNodeVO
     */
    public static <V> OptionNodeVO<V> covert(Map<V, String> map, V defaultValue) {
        List<Node<V>> collect = map.entrySet().stream().map(m -> new Node<>(m.getKey(), m.getValue())).collect(Collectors.toList());
        return new OptionNodeVO<>(collect, defaultValue);
    }

    /**
     * 过滤
     *
     * @return
     */
    public void filter(Function<T, Boolean> fun) {

        data = data.stream().filter(m -> fun.apply(m.id)).collect(Collectors.toList());
    }


    @Data
    public static class Node<T> {

        public Node(T id, String name) {
            this(id, name, null, null, null);
        }

        public Node(T id, String name, Object value1) {
            this(id, name, value1, null, null);
        }

        public Node(T id, String name, Object value1, Object value2) {
            this(id, name, value1, value2, null);
        }

        public Node(T id, String name, Object value1, Object value2, Object value3) {

            this.id = id;
            this.name = name;
            this.value1 = value1;
            this.value2 = value2;
            this.value3 = value3;

        }

        public Node(T id, String name, Object value1, Object value2, Object value3, Object value4) {

            this.id = id;
            this.name = name;
            this.value1 = value1;
            this.value2 = value2;
            this.value3 = value3;

        }

        /**
         * 唯一主键
         */
        private T id;

        /**
         * 前端显示值-下拉框显示值
         */
        private String name;

        /**
         * 额外参数1
         */
        private Object value1;
        private Object value2;
        private Object value3;
        private Object value4;

    }
}
